【注】所有代码挂在我的github上
在前两篇的基础上,正式引入sizzle引擎,这里不详细介绍sizzle引擎。
我们在前两篇的jQuery.fn.init
的方法是
1 | var init = function(jQuery){ |
这里得到的结果是个数组,而不是我们需要的类数组结构的DOM集合HTMLCollection
1.引入Sizzle引擎
下载Sizzle,将sizzle.js
文件复制在src/sizzle
中,并且改造Sizzle成模块化的
1 | //1-头部注释 |
同时增加一个初始化文件src/sizzle/init.js
1 | import Sizzle from './sizzle.js'; |
我们可以在jquery源码中找到全部将sizzle赋值的语句,这些我们暂时先不管
1 | jQuery.find = Sizzle; |
修改jquery.js
1 | import jQuery from './core'; |
测试:1
2
3<div><span>1</span></div>
<div><span>2</span></div>
<div>3</div>
1 | var div = $('div'); |
最后的结果仍然是个DOM集合数组
2.$.merger
方法
1 | jQuery.fn = jQuery.prototype = { |
1 | jQuery.extend({ |
测试1
2
3
4
5
6
7
8
9var divs = $.find('div'); //纯数组
var $div1 = $.merge(['hi'], divs); //右边的数组合并到左边的数组,形成一个新数组
var $div2 = $.merge({
0: 'hi',
length: 1
}, divs); //右边的数组合并到左边的对象,形成一个新的类数组对象
console.log($div1);
console.log($div2);
我们发现,只需要将$.merger
的第一个参数first设置为this(jQuery的示例对象,length已经默认设置为0),第二个参数second设置为搜索到的DOM集合就可以得到DOM集合类数组对象。
修改src/init.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var init = function(jQuery){
jQuery.fn.init = function (selector, context) {
if (!selector) {
return this;
} else {
var elemList = jQuery.find(selector);
if (elemList.length) {
jQuery.merge( this, elemList ); //this是jQuery实例,默认实例属性 .length 为0
}
return this;
}
};
jQuery.fn.init.prototype = jQuery.fn;
};
export default init;
3.扩展 $.fn.find
我们虽然能使用$.find方法,但是它并不支持链式,所以我们需要扩展之。
1 | jQuery.fn.extend({ |
4.记录栈-pushStack方法
参考浏览器的历史记录栈,将检索到的jQuery实例放入到栈中,方便存取数据,其中jquery中有一个方法$.end
放回上次检索的jQuery对象,使用记录栈能够很方便的实现。
1 | jQuery.fn = jQuery.prototype = { |
重新修改第3部分的代码
1 | jQuery.fn.extend({ |
从性能上考虑,改为这样,建设merge里面的遍历
1 | jQuery.fn.extend({ |
5.$.fn.end
、$.fn.eq
和 $.fn.get
1 | jQuery.fn.extend({ |
6.todolist
我们花了三篇博客写到这里,其实还是有很多没有完全实现,后面的部分也是参照jquery的源码,DIY一个自己的jquery,还有一些没有实现的点
$.fn.init
第二个参数context上下文还没实现$.fn.find
返回结果中可能带着重复的DOM
例如:1
2
3
4
5<div><div><span>hi</span></div></div>
<script>
var $span = $('div').find('span');
console.log($span); //返回两个span
</script>
下面的部分留作再写几篇博客
参考阅读: